import * as React from 'react';
import { Set, Rect, Path } from 'react-raphael';
import { Point, Range, OperaType } from '../../reducer/const';
import { COLOR } from './Style';
import { PathString } from '../../util/eventUtil';

import TaskNode, { INodeProps } from './TaskNode';


export default class BranchNode extends TaskNode {

    constructor(props: INodeProps) {
        super(props);
        const {history} = this.props;
        if (history) {
            this.colorStroke = COLOR.stroke2;
            this.colorIcon = COLOR.icon2;
            this.colorFill = COLOR.fill2;
            this.strokeWidth = 3;
            this.strokeIconWidth = 2;
        } else {
            this.colorStroke = COLOR.stroke1;
            this.colorIcon = COLOR.end2;
            this.colorFill = COLOR.fill1;
            this.strokeWidth = 1;
            this.strokeIconWidth = 2;
        }
    }

    getRefs = () => {
        return this.refs;
    }

    render() {
        return (
            <Set>
                {this.renderSelect()}
                {this.renderRect()}
                {this.renderIcon()}
            </Set >
        );
    }


    renderRect() {
        const {range} = this.state;
        const {selectId, id, operaType, history} = this.props;
        const selected = id === selectId;
        let cursorAttr = selected ? { 'cursor': 'default', 'z-index': 11 } : { 'cursor': 'default', 'z-index': 10 };
        if (!history) {
            if (OperaType.Linked === operaType) {
                cursorAttr.cursor = 'crosshair';
            } else if (selectId === id) {
                cursorAttr.cursor = 'move';
            }
        }
        let rectAttr = { 'stroke': `${this.colorStroke}`, 'fill': `${this.colorFill}`, 'stroke-width': `${this.strokeWidth}` };
        rectAttr = Object.assign(rectAttr, cursorAttr);
        return <Path ref='rectPath' attr={rectAttr} d={this.getRectPath(range)} {...this.getEventProps() } />;
    }

    getRectPath(range: Range) {
        const pathString: PathString = new PathString();
        pathString.M(range.x + range.width / 2, range.y).L(range.x + range.width, range.y + range.height / 2);
        pathString.L(range.x + range.width / 2, range.y + range.height).L(range.x, range.y + range.height / 2);
        pathString.Z();
        return pathString.toString();
    }

    renderIcon(): JSX.Element {
        const {range} = this.state;
        const pathString: string = this.getIconPath(range);
        let iconAttr = this.getIconAttr();
        return <Path ref='icon' attr={iconAttr} d={pathString} {...this.getEventProps() } />;
    }

    getIconAttr() {
        const iconAttr = { 'stroke': `${this.colorIcon}`, 'fill': `none`, 'stroke-width': `${this.strokeIconWidth}` };
        return iconAttr;
    }

    getIconPath(range: Range) {
        const sizeh1: number = 6;
        const sizev1: number = 8;
        const center: Point = new Point(range.x + range.height / 2, range.y + range.height / 2);
        const pathString: PathString = new PathString();
        pathString.M(center.x - this.strokeIconWidth / 2, center.y - sizeh1).L(center.x - this.strokeIconWidth / 2, center.y + sizeh1);
        pathString.L(center.x + this.strokeIconWidth / 2, center.y + sizeh1).L(center.x + this.strokeIconWidth / 2, center.y - sizeh1);
        pathString.Z();

        pathString.M(center.x - sizev1, center.y - this.strokeIconWidth / 2).L(center.x + sizev1, center.y - this.strokeIconWidth / 2);
        pathString.M(center.x + sizev1, center.y + this.strokeIconWidth / 2).L(center.x - sizev1, center.y + this.strokeIconWidth / 2);
        pathString.Z();

        return pathString.toString();
    }

    updateIcon = (point: Point, range: Range): void => {
        const icon = this.getRefs().icon && this.getRefs().icon.getElement();
        if (icon) {
            const pathString: string = this.getIconPath(range);
            icon.attr({ path: pathString });
        }
    }

    updateOtherElement = (point: Point, range: Range) => {
        const rectPath = this.getRefs().rectPath && this.getRefs().rectPath.getElement();
        if (rectPath) {
            const pathString: string = this.getRectPath(range);
            rectPath.attr({ path: pathString });
        }
    }

}
